rm(list = ls())
setwd("~/Projects/news_tweets")
## --- Load Packages --- ##
library(rtweet)
library(dplyr)
library(ggplot2)
library(rvest)
library(tidyr)
library(wordcloud2)
library(igraph)
library(ggraph)
library(stringr)
library(tm)
library(tidytext)
library(stringi)
library(lubridate)
library(gganimate)
library(htmlwidgets)
## --- Set Stylings --- ###
knitr::opts_chunk$set(message=FALSE, warning=FALSE)
theme_set(
theme_bw(base_size = 14) +
theme(
plot.title = element_text(face = "bold", size = 14,
margin = margin(0, 0, 4, 0, "pt")),
plot.subtitle = element_text(size = 12),
plot.caption = element_text(size = 6, hjust = 0),
axis.title = element_text(size = 10),
panel.border = element_blank()
)
)
## --- Global Variables --- ##
# Define Color
Mycol <- RColorBrewer::brewer.pal(8, "Dark2")
# Define http pattern
http <- paste("http.*","https.*", sep = "|")
# Define Stopwords
stopwords <- data_frame(
word = stopwords("german")
) %>% rbind(
data_frame(word = c("t.co","via","mal","dass","mehr", "amp","https",
"beim", "ab","sollen","ganz","sagt",
"schon","rt","gibt", "ja", "natürlich"))
)Deutschsprachige Tweets die den Hashtag “#GERSWE” beinhalten. Die Tweets wurden mit Hilfe des R Packetes rtweet über die REST API ausgelesen. Der gesamte Code ist hier einzusehen.
load("../../data/gerswe.Rda")
attr(rt$created_at, "tzone") <- "Europe/Berlin"
start <- as.POSIXct("2018-06-23 19:00", tz = "Europe/Berlin")
end <- start + minutes(220)
gamestart <- as.POSIXct("2018-06-23 20:00", tz = "Europe/Berlin")
gameend <- gamestart + minutes(113)
rt_small <- rt %>%
# mutate(created_at = as.POSIXct(created_at + hours(2))) %>%
filter(created_at >= start) %>%
filter(created_at <= end) rt_small %>%
ts_plot("1 minute",
color = Mycol[3]) +
geom_vline(xintercept = gamestart, color=Mycol[1], linetype = 2) +
geom_vline(xintercept = gameend, color=Mycol[1], linetype = 2) +
theme(plot.title = element_text(face = "bold"),
axis.text.x = element_blank()) +
labs(
x = NULL, y = NULL,
title = "Tweets zum Spiel Deutschland - Mexiko",
subtitle = paste("Zeitraum:",min(rt$created_at),"bis",max(rt$created_at))
) Welche Tweets wurden am häufigsten geteilt? Die top 10 sind:
rt_small %>%
filter(is_retweet == FALSE ) %>%
dplyr::select(screen_name, text, retweet_count) %>%
group_by(screen_name, text) %>%
summarise(retweet_count = sum(retweet_count)) %>%
arrange(desc(retweet_count)) %>%
.[1:10,] %>%
#knitr::kable(align = "l")
htmlTable::htmlTable(align="l")| screen_name | text | retweet_count | |
|---|---|---|---|
| 1 | DFB_Team | Wahnsinn in Sotschi! Wir gewinnen in Unterzahl und letzter Minute gegen Schweden. #ZSMMN #WM2018 #GERSWE 2-1 https://t.co/xx4G32tAut | 3583 |
| 2 | LeroySane19 | Besser spät als nie 😉⚽ Glückwunsch zum Sieg Jungs, am Ende vollkommen verdient! @DFB_Team #DieMannschaft #GERSWE | 1467 |
| 3 | FCBayern |
🇩🇪🇸🇪 Alter Schwede - Sieg in der Nachspielzeit! #GERSWE #DieMannschaft #WM2018 https://t.co/EH7iydh9ad |
1227 |
| 4 | RKiesewetter | Schon irre, mich sprechen vor Spiel #GERSWE 2 CDU-Kollegen an, sagen offen, wenn ich weiter europafreundliche liberale Haltung wie #Merkel in Asyl-/ Migrationsfragen vertrete, würde prominenter CSUler bei der nächsten #BTW gegen mich kandidieren. Soweit lassen wir uns bringen! | 1034 |
| 5 | BVB | 🇩🇪 GLÜCKWUNSCH! Last-Minute-Sieg für @woodyinho und das @DFB_Team! #Reus ebnet mit seinem Ausgleich in der 48. Minute den Weg für das deutsche Team! 🇩🇪 #GERSWE 🇸🇪 #BoRUSSIA2018 https://t.co/u6Gi9BlWCb | 835 |
| 6 | mbfussball |
BEST NEVER REST! Dieses Team kommt immer zurück! @ToniKroos schießt das @DFB_Team in Führung – der Traum vom Achtelfinale lebt wieder! #GERSWE 🇩🇪🇸🇪 #BestNeverRest https://t.co/YSvol59YXi |
776 |
| 7 | ZDFsport |
“Fußball ist ein einfaches Spiel: 22 Männer jagen 90 Minuten einem Ball nach und am Ende gewinnen immer die Deutschen.” - Gary Lineker #GERSWE | #ZDFwm2018 https://t.co/kWt9Q3l6zp |
726 |
| 8 | anredo | Wenn ich ein Wasser mit Kohlensäure bestelle aber eins ohne bekomme. #GERSWE https://t.co/e2mIwN44Ig | 717 |
| 9 | FCBayern | 🇩🇪 Bärenstarke Leistung, Kapitän! ©💪 @Manuel_Neuer #GERSWE #WM2018 https://t.co/o5SM5CYWwb | 676 |
| 10 | bayer04fussball | Unsere herzlichsten Glückwünsche nach Sotschi! #StärkeBayer #GERSWE 1-2 🇩🇪🇸🇪 https://t.co/BHeIFhmQgy | 521 |
rt_clean <- rt_small %>%
# First, remove http elements manually
mutate(stripped_text = gsub(http,"", text)) %>%
mutate(stripped_text = gsub("gerswe","", text, ignore.case = T))
rt_tidy_words <- rt_clean %>%
# Second, remove punctuation, convert to lowercase, add id for each tweet!
dplyr::select(stripped_text) %>%
unnest_tokens(word, stripped_text) %>%
# Third, remove stop words from your list of words
anti_join(stopwords) %>%
# Count Word occurences in a tweet
count(word, sort = TRUE)
rt_tidy_words %>%
wordcloud2(size = 2,
color = "random-light", backgroundColor = "grey")word_network(rt_clean)Lexikon Ansatz unter Verwendung des SentimentWortschatz
sent <- c(
# positive Wörter
readLines("../../dict/SentiWS_v1.8c_Negative.txt",
encoding = "UTF-8"),
# negative Wörter
readLines("../../dict/SentiWS_v1.8c_Positive.txt",
encoding = "UTF-8")
) %>% lapply(function(x) {
# Extrahieren der einzelnen Spalten
res <- strsplit(x, "\t", fixed = TRUE)[[1]]
return(data.frame(words = res[1], value = res[2],
stringsAsFactors = FALSE))
}) %>%
bind_rows %>%
mutate(word = gsub("\\|.*", "", words) %>% tolower,
value = as.numeric(value)) %>%
# manche Wörter kommen doppelt vor, hier nehmen wir den mittleren Wert
group_by(word) %>% summarise(value = mean(value)) %>% ungroupsentDF <- rt_clean %>%
# Second, remove punctuation, convert to lowercase, add id for each tweet!
unnest_tokens(word, stripped_text) %>%
left_join(., sent, by="word") %>%
mutate(value = as.numeric(value)) %>%
#filter(!is.na(value)) %>%
mutate(negative = ifelse(value < 0, value, NA),
positive = ifelse(value > 0, value, NA),
negative_d = ifelse(value < 0, 1, 0),
positive_d = ifelse(value > 0, 1, 0)) sentDF.grouped <- sentDF %>%
group_by(status_id) %>%
summarise(mean_value = mean(value, na.rm = T),
sum_value = sum(value, na.rm = T),
positive = sum(positive, na.rm = T),
negative = sum(negative, na.rm = T)) %>%
left_join(., rt_small %>% dplyr::select(status_id, screen_name, text, created_at),
by = "status_id") %>%
filter(!is.na(mean_value))sentDF.grouped %>%
arrange(desc(mean_value)) %>%
select(screen_name, text, mean_value, created_at) %>%
.[1:10,] %>%
htmlTable::htmlTable(align="l")| screen_name | text | mean_value | created_at | |
|---|---|---|---|---|
| 1 | Simone0171 | Heute ist aber Dampf drin! Start gelungen, jetzt dran bleiben🙌🏼👏🏼👊🏼⚽️🇩🇪 #GERSWE #WorldCup18 | 1 | 2018-06-23 20:10:51 |
| 2 | uelmenuelmen | Die Straßen sind leergefegt. Perfekt zum drugs dealen #GERSWE | 0.7299 | 2018-06-23 19:31:48 |
| 3 | thierie01 |
Ich sehe #Löw hat die #Mannschaft perfekt vorbereitet. ➡️ Die Nivea-Lotion ist aufgetragen. ➡️ Die Tattoos sind geölt. ➡️ Die Haare sind perfekt gestylt. Was soll da jetzt schon schiefgehen? #GERSWE #FussballWM2018 #Russia2018WorldCup |
0.7299 | 2018-06-23 19:59:57 |
| 4 | enricoS74 | #GerSwe perfekt!!! Es läuft!!! Auf Wiedersehen Erdogan freaks. | 0.7299 | 2018-06-23 20:39:44 |
| 5 | Telodor567 | Mein Vater meinte, so wie wir spielen, das passt perfekt auf Deutschland generell heute. #GERSWE | 0.7299 | 2018-06-23 20:53:03 |
| 6 | ToniHorvatos | Schweden wird gleich ultra tiefstehen. Wenn sie nur einen Flügelspieler hätten der 1v1 perfekt kann. Stattdessen ist Müller LF. #GERSWE | 0.7299 | 2018-06-23 20:56:23 |
| 7 | TitoUganj | @quotenmeter DFB-Elf und ARD bilden eine homogene lahmarschige Masse. Löw mäandert unter Valium, Kimmich hat die Hosen voll, Müller verkörpert perfekt den Durchschnitt, Götze bester Deutscher und Bartels geht voll aus sich raus (“das geht so nicht”). #gerswe | 0.7299 | 2018-06-23 21:03:35 |
| 8 | MrsOrange | Unser Team ist wie ein mit High Tech vollgestopftes Auto. Alles läuft perfekt und schnurrt, aber sobald irgendwo ein Kontakt wackelt, explodiert die Karre. #WM2018 #GERSWE | 0.7299 | 2018-06-23 21:03:48 |
| 9 | JonasBelling |
11 Millionäre mit perfekt sitzenden Frisuren. Nur Fußball spielen können sie nicht. GerSwe#Sweger |
0.7299 | 2018-06-23 21:03:59 |
| 10 | _misskonfetti | Die Haare liegen nicht perfekt. Das wird nix 🤦♀️ #GERSWE #gomez | 0.7299 | 2018-06-23 21:04:43 |
sentDF.grouped %>%
arrange(mean_value) %>%
select(screen_name, text, mean_value, created_at) %>%
.[1:10,] %>%
htmlTable::htmlTable(align="l")| screen_name | text | mean_value | created_at | |
|---|---|---|---|---|
| 1 | Paeddy1994_yt | Warum nennen wir #LaManschaft nicht gleich „keine Gefahr“? 🙄 #GERSWE #WM2018 | -1 | 2018-06-23 20:08:47 |
| 2 | wanderwitz | Da ist die Gefahr. @Manuel_Neuer #Fußballgott! #GERSWE Aber gutes druckvolles Spiel @DFB_Team… | -1 | 2018-06-23 20:13:47 |
| 3 | mainwasser | Eine solch große Gefahr war Schweden für Deutschland zuletzt 1618-48. #GERSWE | -1 | 2018-06-23 20:39:37 |
| 4 | dj48jupp | #GERSWE In der 40. Min schießt mal einer aus 16 m aufs Tor. Gleich Gefahr. 1/2 Minute später, versuchen sie wieder, den Ball ins Tor zu tragen. Das durch eine vielbeinige Abwehr. ???????????????? | -1 | 2018-06-23 20:41:46 |
| 5 | kfdreizehn | Auf die Gefahr, das ich mich wiederhole, aber ohne defensives Mittelfeld in ein Turnier zu gehen, funktioniert äußerst selten!☝🏻 #wm2018 #GERSWE | -1 | 2018-06-23 20:51:52 |
| 6 | BastiBoers2 |
Mehr Gefahr? #Brandgefährlich bringen! #GERSWE #wm2018 #Ger |
-1 | 2018-06-23 21:13:35 |
| 7 | ElCobra | Auf die Gefahr hin wie ein angegammelter Altinternationaler im Doppelpass zu klingen: So viele Pseudo-Häuptlinge, kein einziger echter Anführer. #GERSWE | -1 | 2018-06-23 21:39:23 |
| 8 | Clausewutz |
Die @afd wird schuld sein, wenn Schland ausscheidet #GERSWE |
-0.9686 | 2018-06-23 19:12:36 |
| 9 | thesoftrockcafe | Wenn Deutschland rausfliegt, sind definitiv nicht Özil, Draxler oder Löw schuld. Sondern die Fanta4 mit ihrem unsäglichen WM-Song! #GERSWE #wm2018 https://t.co/fvlTbORZNE | -0.9686 | 2018-06-23 19:50:40 |
| 10 | FreshFries90 | Haben alle mitgesungen. Wenn es jetzt nichts wird mit dem Sieg ist die deutsche Frau schuld, die sie eingeblendet haben, die nicht mitgesungen hat #GERSWE | -0.9686 | 2018-06-23 19:56:32 |